package com.xique.park.mq.consumer;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.xique.common.core.constant.Constants;
import com.xique.common.core.utils.AliossUtil;
import com.xique.park.bean.domain.*;
import com.xique.park.mq.bean.ParkInMsg;
import com.xique.park.service.biz.service.IParkWxMessageSendBizService;
import com.xique.park.service.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author shd
 * @create 2022/7/29 10:41
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ParkInFinishMqConsumer {

    private final IParkThirdPartyPushService parkThirdPartyPushService;

    private final MsgIdempotentService msgIdempotentService;

    private final IParkMqFailMsgService parkMqFailMsgService;

    private final IParkLaneService parkLaneService;

    private final IParkCarMngtypeService parkCarMngtypeService;

    private final AliossUtil aliossUtil;

    private final IParkWxMessageSendBizService parkWxMessageSendBizService;

    public void receive(ParkInMsg parkInMsg) {
        try {
            Long msgId = parkInMsg.getMsgId();
            if (null != msgId) {
                // 插入数据库，防止重复消费
                if (saveParkMqMsg(parkInMsg)) {
                    ParkIn parkIn = parkInMsg.getParkIn();
                    if (null != parkIn) {
                        Long parkId = parkIn.getParkId();
                        ParkThirdPartyPush parkThirdPartyPush = getParkThirdPartyPush(parkId);
                        // 判断车场是否需要推送进场记录
                        if (parkThirdPartyPush != null && parkThirdPartyPush.getInRecordPush() == Constants.TRUE) {
                            // 组织信息
                            Map<String, Object> paramMap = paramMap(parkIn);

                            // 推送
                            push(parkThirdPartyPush, paramMap, parkId, parkIn);
                        }

                        // 进场消息推送到对应用户的公众号
                        parkWxMessageSendBizService.delayParkInFinishProcess(parkIn);
                    } else {
                        log.warn("[入场通知]-入场消息中的入场信息为空，{}", parkInMsg);
                    }
                } else {
                    log.warn("[入场通知]-消息已经被消费过了，{}", parkInMsg);
                }
            } else {
                log.warn("[入场通知]-入场消息ID为空，{}", parkInMsg);
            }
        } catch (Exception e) {
            // 将处理失败的消息存入数据库
            saveParkMqFailMsg(parkInMsg);

            log.error("[入场通知]-消息处理异常，异常信息：{}，{}", e.getMessage(), parkInMsg);
            e.printStackTrace();
        }
    }

    private boolean saveParkMqMsg(ParkInMsg parkInMsg) {
        String msgMd5 = MD5.create().digestHex(JSON.toJSONString(parkInMsg));
        MsgIdempotent parkMqMsg = new MsgIdempotent();
        parkMqMsg.setMsgMd5(msgMd5);
        parkMqMsg.setCreateTime(new Date());
        return msgIdempotentService.save(parkMqMsg);
    }

    private ParkThirdPartyPush getParkThirdPartyPush(Long parkId) {
        return parkThirdPartyPushService.selectOneByParkId(parkId);
    }

    private Map<String, Object> paramMap(ParkIn parkIn) {
        Map<String, Object> paramMap = new HashMap<>(9);
        paramMap.put("parkId", parkIn.getParkId());
        paramMap.put("carPlate", parkIn.getInCarPlate());
        paramMap.put("inTime", parkIn.getInTime());
        paramMap.put("parkingSerial", parkIn.getParkingSerial());
        paramMap.put("mngType", parkIn.getMngType());
        paramMap.put("inStatus", parkIn.getStatus());

        // 获取图片地址
        paramMap.put("inPic", StrUtil.isNotBlank(parkIn.getInPic()) ? aliossUtil.getJzyGetObjectUrl(parkIn.getInPic()).toString() : "");

        // 获取入场通道名称
        paramMap.put("inLaneName", getLaneName(parkIn.getInLaneId()));

        // 获取管理小类名称
        paramMap.put("mngTypeName", getMngTypeName(parkIn.getMngTypeId()));
        return paramMap;
    }

    private String getMngTypeName(Long mngTypeId) {
        ParkCarMngtype parkCarMngtype = parkCarMngtypeService.getById(mngTypeId);
        if (null != parkCarMngtype) {
            return parkCarMngtype.getName();
        }
        return "";
    }

    private String getLaneName(Long laneId) {
        ParkLane parkLane = parkLaneService.selectParkLaneById(laneId);
        if (null != parkLane) {
            return parkLane.getName();
        }
        return "";
    }

    private void push(ParkThirdPartyPush parkThirdPartyPush, Map<String, Object> paramMap, Long parkId, ParkIn parkIn) {
        String inRecordPushUrl = parkThirdPartyPush.getInRecordPushUrl();
        if (StrUtil.isNotBlank(inRecordPushUrl)) {
            String json = JSON.toJSONString(paramMap);
            String httpResponse = HttpUtil.post(inRecordPushUrl, json);
            log.info("[入场通知]-入场记录推送地址：{}，推送信息：{}，推送结果：{}", inRecordPushUrl, paramMap, httpResponse);
        } else {
            log.warn("[入场通知]-车场未配置进场记录推送地址，车场：{}，{}", parkId, parkIn);
        }
    }

    private void saveParkMqFailMsg(ParkInMsg parkInMsg) {
        ParkMqFailMsg parkMqFailMsg = new ParkMqFailMsg();
        parkMqFailMsg.setMsgId(parkInMsg.getMsgId());
        parkMqFailMsg.setMsg(JSON.toJSONString(parkInMsg));
        parkMqFailMsg.setCreateTime(new Date());
        parkMqFailMsgService.save(parkMqFailMsg);
    }

}
